# -*- coding: UTF-8 -*-
import logging
import socketserver
import datetime
import threading


Format = '%(asctime)-15s  %(thread)-10d %(threadName)-10s %(message)s'
logging.basicConfig(format=Format,datefmt="%Y/%m/%d %H:%M:%S",level = logging.INFO)



class Myhandler(socketserver.StreamRequestHandler):
    def setup(self,clients = {},lock = threading.Lock()) -> None:
        super().setup()
        self.clients = clients
        self.event = threading.Event()
        self.lock = lock

    def handle(self) -> None:
        super().handle()
        with self.lock:
            self.clients[self.client_address] = self.wfile
            logging.info('{}:{} connect'.format(*self.client_address))
        while not self.event.is_set():
            try:
                data = self.rfile.readline().decode().strip()
                msg = "{:%Y/%m/%d %H:%M:%S} form{}:{},mesg = {}\n".format(datetime.datetime.now(), *self.client_address, data).encode()
                if data:
                    with self.lock:
                        for p in self.clients.values():
                            p.write(msg)
                            p.flush()
                else:
                    raise ConnectionError
            except:
                with self.lock:
                    logging.error('{}:{} disconnect'.format(*self.client_address))
                    self.clients.pop(self.client_address)
                    break


    def finish(self) -> None:
        super().finish()
        self.event.set()

server = socketserver.ThreadingTCPServer(('127.0.0.1',9999),Myhandler)
threading.Thread(target=server.serve_forever,name = 'server',daemon=True).start()
server.daemon_threads = True

while True:
    cmd = input('>>>').strip()
    if cmd == 'quit':
        server.server_close()
        break
